/**
*  deferredmessage.h
*
*  Base class for the deferred consumer base and the
*  deferred return.
*
*  @copyright 2016
*/

/**
*  Include guard
*/
#pragma once

/**
*  Dependencies
*/
#include "deferred.h"
#include "stack_ptr.h"
#include "message.h"

/**
*  Start namespace
*/
namespace AMQP {

	/**
	*  Forward declarations
	*/
	class BasicHeaderFrame;
	class BodyFrame;

	/**
	*  Base class for deferred consumers
	*/
	class DeferredMessage :	public Deferred
	{
	private:
		/**
		*  Size of the body of the current message
		*  @var    uint64_t
		*/
		uint64_t _bodySize = 0;

		/**
		*  Process the message headers
		*
		*  @param  frame   The frame to process
		*/
		void process(BasicHeaderFrame &frame);

		/**
		*  Process the message data
		*
		*  @param  frame   The frame to process
		*/
		void process(BodyFrame &frame);

		/**
		*  Indicate that a message was done
		*/
		virtual void complete() = 0;

		/**
		*  Frames may be processed
		*/
		friend class BasicHeaderFrame;
		friend class BodyFrame;

	protected:
		/**
		*  Callback for incoming headers
		*  @var    HeaderCallback
		*/
		HeaderCallback _headerCallback;

		/**
		*  Callback for when a chunk of data comes in
		*  @var    DataCallback
		*/
		DataCallback _dataCallback;

		/**
		*  The message that we are currently receiving
		*  @var    stack_ptr<Message>
		*/
		stack_ptr<Message> _message;

		/**
		*  Constructor
		*
		*  @param  failed  Have we already failed?
		*  @param  channel The channel we are consuming on
		*/
		DeferredMessage(bool failed) : Deferred(failed){}
	public:
	};

	/**
	*  End namespace
	*/
}
